﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoreLims.Models.CoreLims
{
    public static class RetentionSampleExtension
    {
        /// <summary>
        /// 复制登录样品中的信息
        /// </summary>
        /// <param name="sample"></param>
        public static RetentionSample CopySample(this RetentionSample rs, SampleSample sample, CoreLimsContext dbContext)
        {
            rs.Id = sample.Id;
            rs.MaterialCode = sample.MaterialId;
            rs.Name = sample.Name;
            rs.SampleId = sample.SampleId;
            rs.SampleNumber = sample.SampleNumber;
            rs.BatchId = sample.BatchId;
            rs.Classification = sample.Classification;
            rs.GenricClass = sample.GenricClass;
            rs.Site = sample.Site;
            rs.Group = sample.Group;
            rs.RegistrationTime = DateTime.Now;

            var rc = dbContext.RetentionConfig.Where(s => s.Id == sample.RetentionConfigId).FirstOrDefault();
            if (rc != null)
            {
                rs.Container = rc.Container;
                rs.Quantity = rc.Quantity;
                rs.Unit = rc.Unit;
                rs.ContainerNumber = rc.ContainerNumber;
                rs.Remind = rc.Remind;
                rs.KeepTo = rc.KeepTo();
                rs.DisApproval = rc.DisApproval;
                rs.UseApproval = rc.UseApproval;
            }
            return rs;
        }

        public static RetentionSample getRetentionSample(this RetentionSample rs, CoreLimsContext dbContext, string Id) =>
              dbContext.RetentionSample.FirstOrDefault(s => s.Id == Id);

        public static RetentionUse getRetentionUse(this RetentionSample rs, CoreLimsContext dbContext, string Id) =>
            dbContext.RetentionUse.FirstOrDefault(s => s.Id == Id);

        /// <summary>
        /// 根据IDS获取列表,顺序根据ID号由小到大排序
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids">“,”分隔的字符串</param>
        /// <returns></returns>
        public static List<RetentionSample> getListByIds(this RetentionSample rs, CoreLimsContext dbContext, string Ids)
        {
            var arr = Ids.Split(',');
            return dbContext.RetentionSample.Where(s => arr.Contains(s.Id)).OrderBy(s => s.SampleId).ToList();
        }

        /// <summary>
        /// 查询所有待接收样品
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids"></param>
        /// <returns></returns>
        public static List<RetentionSample> getRegistrationList(this RetentionSample rs, CoreLimsContext dbContext) =>
            dbContext.RetentionSample.Where(s => s.ReceptionTime == null ).OrderByDescending(x=> x.SampleId).ToList();

        /// <summary>
        /// 查询所有已接收但未处置的样品
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids"></param>
        /// <returns></returns>
        public static List<RetentionSample> getRecipientList(this RetentionSample rs, CoreLimsContext dbContext) =>
            dbContext.RetentionSample.Where(s =>s.DisposerTime == null && s.ReceptionTime != null).OrderByDescending(x => x.SampleId).ToList();

        /// <summary>
        /// 查询所有已处置样品
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids"></param>
        /// <returns></returns>
        public static List<RetentionSample> getDisposerList(this RetentionSample rs, CoreLimsContext dbContext, string Ids) =>
            dbContext.RetentionSample.Where(s => s.DisposerTime != null).OrderByDescending(x => x.SampleId).ToList();

        /// <summary>
        /// 根据样品的一、二级分类查询
        /// </summary>
        /// <param name="inv"></param>
        /// <param name="dbContext"></param>
        /// <param name="Classification"></param>
        /// <param name="GenricClass"></param>
        /// <returns></returns>
        public static List<RetentionSample> getBySampleType(this RetentionSample rs, CoreLimsContext dbContext, string Classification, string GenricClass = null)
        {
            if (string.IsNullOrEmpty(GenricClass))
            {
                return dbContext.RetentionSample.Where(s => s.Classification == Classification ).OrderBy(x => x.ReceptionTime).ToList();
            }
            else
            {
                return dbContext.RetentionSample.Where(s => s.Classification == Classification && s.GenricClass == GenricClass ).OrderBy(x => x.ReceptionTime).ToList();
            }
        }

        public static List<RetentionSample> getBySampleId(this RetentionSample rs, CoreLimsContext dbContext, string SampleId) =>
            dbContext.RetentionSample.Where(s => s.SampleId == SampleId ).OrderByDescending(x => x.SampleId).ToList();

        public static List<RetentionSample> getBySampleNumber(this RetentionSample rs, CoreLimsContext dbContext, string SampleNumber) =>
            dbContext.RetentionSample.Where(s => s.SampleNumber == SampleNumber ).OrderByDescending(x => x.SampleId).ToList();

        public static List<RetentionSample> getByBatchId(this RetentionSample rs, CoreLimsContext dbContext, string BatchId) =>
            dbContext.RetentionSample.Where(s => s.BatchId == BatchId ).OrderByDescending(x => x.SampleId).ToList();

        /// <summary>
        /// 根据 名称 模糊查询
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        public static List<RetentionSample> getBySampleName(this RetentionSample rs, CoreLimsContext dbContext, string Name) =>
            dbContext.RetentionSample.Where(s => s.Name.Contains(Name)).ToList().OrderBy(x => x.Name).ToList();

        /// <summary>
        /// 添加留样
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="sampleList"></param>
        /// <returns></returns>
        public async static Task<string> Add(this RetentionSample rs, CoreLimsContext dbContext, List<SampleSample> sampleList)
        {
            foreach (var sample in sampleList)
            {
                var rsample = new RetentionSample();
                sample.Name = sample.Name;
                sample.SampleId = sample.SampleId;
                sample.SampleNumber = sample.SampleNumber;
                sample.BatchId = sample.BatchId;
                sample.Classification = sample.Classification;
                sample.GenricClass = sample.GenricClass;
                sample.Site = sample.Site;
                sample.Group = sample.Group;

                dbContext.Add(rsample);
            }
            try
            {
                await dbContext.SaveChangesAsync();
            }
            catch
            {
                return "添加留样时出错，请联系管理员！";
            }
            return "留样添加成功！";
        }

        /// <summary>
        /// 接收留样
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids">被接收的留样Ids</param>
        /// <param name="RecipientId">接收人ID</param>
        /// <param name="RecipientName">接收人姓名</param>
        /// <param name="Note">留样备注</param>
        /// <param name="jsonRetentionConfig">留样配置参数</param>
        /// <returns></returns>
        public async static Task<string> Recipient(this RetentionSample rs, CoreLimsContext dbContext, string Ids, string RecipientId, string RecipientName, string Note, string jsonRetentionConfig, string KeepTo)
        {
            var rconfig = JsonConvert.DeserializeObject<RetentionConfig>(jsonRetentionConfig);  //反序列化，字符串转换为类
            var list = rs.getListByIds(dbContext, Ids);
            foreach (var record in list)
            {
                record.RecipientId = RecipientId;
                record.RecipientName = RecipientName;
                record.Note = Note;
                record.ReceptionTime = DateTime.Now;
                if (KeepTo != null)
                {
                    record.KeepTo = DateTime.Parse(KeepTo);
                }

                record.Container = rconfig.Container;
                record.ContainerNumber = rconfig.ContainerNumber;
                record.Quantity = rconfig.Quantity * rconfig.ContainerNumber;
                record.Unit = rconfig.Unit;
                record.Remind = rconfig.Remind;
                record.Position = rconfig.Position;
                record.StorageConditionsId = rconfig.StorageConditions;
                dbContext.Update(record);
            }
            await dbContext.SaveChangesAsync();
            return "留样接收成功！";
        }

        /// <summary>
        /// 留样处置
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids">被处置留样的Ids</param>
        /// <param name="DisposerId">处置人ID</param>
        /// <param name="DisposerName">处置人姓名</param>
        /// <param name="DisposalInstructions">处置说明</param>
        /// <returns></returns>
        public static string Disposal(this RetentionSample rs, CoreLimsContext dbContext, string Ids, string DisposerId, string DisposerName, string DisposalInstructions = null)
        {
            var list = rs.getListByIds(dbContext, Ids);
            foreach (var record in list)
            {
                record.DisposerId = DisposerId;
                record.DisposerName = DisposerName;
                record.DisposalInstructions = DisposalInstructions;
                record.DisposerTime = DateTime.Now;
                dbContext.Update(record);
            }
            dbContext.SaveChanges();
            return "留样处置成功！";
        }

        /// <summary>
        /// 根据留样ID添加留样领用记录，支持批量添加。并返回第一个成功领用的实例
        /// </summary>
        /// <param name="rs"></param>
        /// <param name="dbContext"></param>
        /// <param name="Ids"></param>
        /// <param name="ContainerNumber"></param>
        /// <param name="Quantity"></param>
        /// <param name="Note"></param>
        /// <returns></returns>
        public static RetentionUse AddRetentionUse(this RetentionSample rs, CoreLimsContext dbContext, string Ids, int ContainerNumber, decimal Quantity, string Note, string UserId, string UserName, out string st)
        {
            var list = SAMPLE.RetentionSample.getListByIds(dbContext, Ids);
            var ru = new RetentionUse(); // 返回第一个成功领用的实例
            String title = "领用总数：" + list.Count;
            StringBuilder sample = new StringBuilder();
            int fal = 0;
            int sucees = 0; // 用来指示第一个成功的记录

            foreach (var record in list)
            {
                if (ContainerNumber > record.ContainerNumber || Quantity > record.Quantity)
                {
                    sample.Append(record.SampleId + ",");
                    fal++;
                }
                else
                {
                    var use = new RetentionUse();
                    use.ContainerNumber = ContainerNumber;
                    use.Quantity = Quantity;
                    use.Note = Note;
                    use.Unit = record.Unit;
                    use.UserId = UserId;
                    use.UserName = UserName;
                    use.RetentionSampleId = record.Id;
                    use.SampleId = record.SampleId;
                    dbContext.Add(use);

                    record.ContainerNumber -= ContainerNumber;
                    record.Quantity -= Quantity;
                    dbContext.Update(record);

                    if (sucees == 0) ru = use;
                }
            }
            dbContext.SaveChanges();

            if (fal > 0) 
                st = title + " 成功数：" + (list.Count - fal) + " 失败数：" + fal + " 失败样品：" + sample.ToString();
            else
                st = title + " 成功数：" + (list.Count - fal);
            return ru;
        }

    }
}
